package com.beiding.jsonanalyzer.analyze.func.base;

import com.beiding.jsonanalyzer.analyze.func.FuncBase;
import com.beiding.jsonanalyzer.flow.ValueNode;

import java.util.*;

/**
 * 简单聚合函数
 *
 * @author 丁常磊
 * @date 2022/5/30 9:54
 */

public abstract class EasyAggFunc implements FuncBase {


    /**
     * 聚合的结果
     */
    private List<ValueNode> valueNodes = new ArrayList<>();

    /**
     * 内核函数
     */
    protected FuncBase core;

    /**
     * 去重操作不是一个函数,只是一个参数
     */
    protected boolean distinct;

    /**
     * 设置内核函数以及是否去重
     * @param core
     * @param distinct
     */
    public void config(FuncBase core, boolean distinct) {
        this.core = core;
        this.distinct = distinct;
    }

    @Override
    public boolean checkAgg() {

        //不支持多层复合嵌套

        if (core.checkAgg()) {
            throw new UnsupportedOperationException("暂不支持多层聚合函数嵌套");
        }

        return true;
    }


    @Override
    public Object executeOne(ValueNode valueNode) {
        //聚合函数也支持单个值执行. 如果一定要单个执行,则返回自身简单结果
        Object one = core.executeOne(valueNode);
        return agg(Collections.singletonList(one));
    }

    @Override
    public void pugAgg(ValueNode valueNode) {
        valueNodes.add(valueNode);
    }

    @Override
    public void resetAgg() {
        valueNodes.clear();
    }

    @Override
    public Object aggGet() {

        List<Object> list;

        if (distinct) {
            //如果去重
            Set<Object> r = new HashSet<>();
            for (ValueNode valueNode : valueNodes) {
                Object one = core.executeOne(valueNode);
                r.add(one);
            }
            list = new ArrayList<>(r);
        } else {
            //如果不去重
            list = new ArrayList<>();
            for (ValueNode valueNode : valueNodes) {
                Object one = core.executeOne(valueNode);
                list.add(one);
            }
        }


        //聚合产生结果
        return agg(list);
    }

    public abstract Object agg(List<Object> list);

}
